package com.vcredit.creditcat.service.product.hl;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.vcredit.bird.enumtype.CreditCardBankEnum;
import com.vcredit.creditcat.enumtype.AuthItemEnum;
import com.vcredit.creditcat.enumtype.MerchantProductEnum;
import com.vcredit.creditcat.enumtype.auth.SupplementItemEnum;
import com.vcredit.creditcat.enumtype.hl.EducationEnum;
import com.vcredit.creditcat.enumtype.hl.HlOccupationEnum;
import com.vcredit.creditcat.enumtype.hl.HouseHoldEnum;
import com.vcredit.creditcat.enumtype.hl.MarriageEnum;
import com.vcredit.creditcat.exception.ResourceException;
import com.vcredit.creditcat.model.AuthCreditcard;
import com.vcredit.creditcat.model.AuthPersonalAddress;
import com.vcredit.creditcat.model.CustAccount;
import com.vcredit.creditcat.model.CustProductApply;
import com.vcredit.creditcat.model.CustSupplementItem;
import com.vcredit.creditcat.model.base.AbstractItem;
import com.vcredit.creditcat.service.product.ICreditCommonService;
import com.vcredit.creditcat.service.product.IProductApplyNewService;
import com.vcredit.creditcat.service.product.shared.ProductApplyServiceAdaptor;
import com.vcredit.creditcat.util.ConcurrentDateUtil;
import com.vcredit.creditcat.util.RSAUtil;
import com.vcredit.creditcat.util.Utility;
import com.vcredit.creditcat.vo.ProductApplyResultVo;
import com.vcredit.creditcat.vo.auth.AuthIdentityExt;
import com.vcredit.creditcat.vo.auth.AuthMobileExt;
import com.vcredit.creditcat.vo.auth.AuthPersonalInfoExt;
import com.vcredit.creditcat.vo.auth.CreditAssureExt;
import com.vcredit.creditcat.vo.product.hl.HlInfoVo;
import com.vcredit.creditcat.vo.product.hl.HlReturnInfoVo;
import com.vcredit.framework.annotation.Log;
import com.vcredit.framework.util.HttpRequest;
import com.vcredit.framework.util.JacksonUtil;

/**
 * 还乐申请实现类
 * 
 * @author zhaoqi01
 *
 */
@Service(ProductApplyServiceAdaptor.BEANNAME_PREFIX + "31")
public class HLApplyServiceImpl implements IProductApplyNewService {
	@Autowired
	@Qualifier("productStrategyContext")
	private ICreditCommonService creditCommonApplyService;

	@Value("${resource.soft.url}")
	private String imagUrl;

	// 对接所用url
	@Value("${product.hl.url}")
	private String creditHLUrl;
	// 公钥
	@Value("${xinyongmao.publicKey}")
	private String publicKey;
	// 私钥
	@Value("${xinyongmao.privateKey}")
	private String privateKey;

	private static Logger logger = LoggerFactory.getLogger(HLApplyServiceImpl.class);
	// 参数定义
	private static final String successStatus = "1";
	private static final String faildStatus = "-1";// 异常
	private static final String refuseStatus = "0";
	private static final Integer liveStatus = 2;
	private static final String reportType = "10";
	private static final String productType = "XYM";
	private static final String invitationCode = "TQ1828";
	private static final String yes = "是";
	private static final String no = "否";
	private static final String huanleException = "还乐申请贷款异常!";
	/***
	 * 入口方法
	 */
	@Log
	@Override
	public ProductApplyResultVo apply(Map<Integer, AbstractItem> custAuthInfoMap, Map<Long, CustSupplementItem> custSupplementItemMap, Map<String, Object> otherParams) {
		ProductApplyResultVo productApplyResultVo = new ProductApplyResultVo();
		HlReturnInfoVo authPersonal = new HlReturnInfoVo();
		try {

			// 提交参数
			// 生成密码
			String password = Utility.getRandom(8).toString();

			Object commitEntity = this.ProductCommitParam(custAuthInfoMap, custSupplementItemMap, otherParams, password);
			// 提交信息
			authPersonal = this.commit(commitEntity);
			// 封装返回信息
			productApplyResultVo = this.paraReturn(1, authPersonal.getMsg(), this.getSaveAuditResultParam(authPersonal, password));
		} catch (Exception e) {
			logger.error("还乐贷款申请异常了：", e);
			productApplyResultVo = this.paraReturn(0, e.getMessage(), null);
		}
		return productApplyResultVo;
	}

	/**
	 * 返回封装信息
	 * 
	 * @param code
	 * @param message
	 * @param apply
	 * @return
	 */
	public ProductApplyResultVo paraReturn(int code, String message, CustProductApply apply) {
		ProductApplyResultVo productApplyResultVo = new ProductApplyResultVo();
		productApplyResultVo.setCode(code);
		productApplyResultVo.setMsg(message);
		productApplyResultVo.setCustProductApply(apply);
		return productApplyResultVo;
	}

	/**
	 * 提交资料
	 * 
	 * @param submitDto
	 * @return
	 * @throws Exception
	 */
	@Log
	public HlReturnInfoVo commit(Object submitDto) throws Exception {
		HlReturnInfoVo authPersonal = null;
		try {
			logger.info(creditHLUrl.concat("customer/submitInfo"));
			String paramJson = JacksonUtil.Obj2Json(submitDto);
			String recodeJson = this.encodeJsonParam(paramJson);
			//logger.info("请求还乐json:" + paramJson);
			String resultJson = HttpRequest.doJson(creditHLUrl.concat("customer/submitInfo"), recodeJson);
			String decodeJsonParam = this.decodeJsonParam(resultJson);
			logger.info("还乐申请 返回" + decodeJsonParam + "!!!");
			authPersonal = JacksonUtil.Json2Obj(decodeJsonParam, new TypeReference<HlReturnInfoVo>() {
			});
		} catch (Exception e) {
			logger.error(huanleException, e);
		}
		return authPersonal;
	}

	private String encodeJsonParam(String jsonParam) throws UnsupportedEncodingException, Exception {
		// 加密
		String requestContentBase64 = Base64.encodeBase64String(RSAUtil.encryptByPrivateKey(jsonParam.getBytes("utf-8"), this.privateKey));
		return requestContentBase64;
	}

	private String decodeJsonParam(String respJson) throws Exception {
		String result = "";
		// 解密
		byte[] res = RSAUtil.decryptBASE64(respJson);
		result = new String(RSAUtil.decryptByPublicKey(res, this.publicKey));
		return result;
	}

	/**
	 * 封装返回实体类
	 * 
	 * @param input
	 * @return
	 * @throws Exception
	 */
	public CustProductApply getSaveAuditResultParam(HlReturnInfoVo input, String password) throws Exception {
		CustProductApply custProductApply = new CustProductApply();

		custProductApply.setAuditTime(ConcurrentDateUtil.formatDateTime(new Date()));
		String flowNo = Utility.nextCode(MerchantProductEnum.creditHl.name().toUpperCase());
		custProductApply.setFlowNo(flowNo);
		// 失败
		if (refuseStatus.equals(input.getStatus())) {
			custProductApply.setRejectMsg(input.getMsg());
			custProductApply.setSuggestion("");
			custProductApply.setIsApply(true);
			custProductApply.setAuditResult(0);
			custProductApply.setCreditApplyTime(ConcurrentDateUtil.formatDateTime(ConcurrentDateUtil.addDayTime(new Date(), 30)));
			return custProductApply;
		}
		// 请求错误
		if (faildStatus.equals(input.getStatus())) {
			throw new Exception("提交异常，请稍后重试！");
		}
		// 成功返回
		if (successStatus.equals(input.getStatus())) {
			custProductApply.setRejectMsg(input.getMsg());
			// custProductApply.setCreditExpiretime(input.getContent().getExpire_date());
			custProductApply.setIsApply(false);
			// custProductApply.setCreditApplyTime(input.getContent().getExpire_date());
			// custProductApply.setTotalServiceRate(new
			// BigDecimal(input.getContent().getTotalRate()));
			// custProductApply.setCreditAmt(Integer.parseInt(input.getContent().getAmount()));
			custProductApply.setAuditResult(2);
			custProductApply.setThirdPwd(this.password(password));
		}
		return custProductApply;
	}

	/**
	 * 封装提交参数
	 * 
	 * @param itemMap
	 * @param otherParams
	 * @return
	 * @throws ResourceException
	 * @throws Exception
	 */

	public Object ProductCommitParam(Map<Integer, AbstractItem> itemMap, Map<Long, CustSupplementItem> custSupplementItemMap, Map<String, Object> otherParams, String password) throws ResourceException, Exception {
		// 职业信息
		// 人脸识别（基本信息+地址信息）
		AuthPersonalInfoExt authPersonal = JacksonUtil.Json2Obj(custSupplementItemMap.get(SupplementItemEnum.HL_BASE_INFO.getItemId()).getDataEntity(), new TypeReference<AuthPersonalInfoExt>() {
		});
		// 地址信息
		List<AuthPersonalAddress> personalAddrList = authPersonal.getPersonalAddrList();
		// 手机认证 补充项
		AuthMobileExt mobile = JacksonUtil.Json2Obj(custSupplementItemMap.get(SupplementItemEnum.HL_MOBILE.getItemId()).getDataEntity(), new TypeReference<AuthMobileExt>() {
		});
		// 高级实名
		AuthIdentityExt identity = (AuthIdentityExt) itemMap.get(AuthItemEnum.VERIFY_FACE_PAIR.getCode());

		// 账户
		CustAccount custAccount = (CustAccount) otherParams.get("custAccount");
		// 机构版征信
		CreditAssureExt netCredit = (CreditAssureExt) itemMap.get(AuthItemEnum.FOREIGN_CREDIT.getCode());
		// 绑卡信息
		AuthCreditcard creditcard = (AuthCreditcard) itemMap.get(AuthItemEnum.CREDIT_CARD.getCode());

		HlInfoVo infoVo = new HlInfoVo();
		infoVo.setReginMobile(custAccount.getUserName());// 注册手机号
		infoVo.setReginPassword(password);// 注册密码
		infoVo.setInvitationCode(invitationCode);// 推荐码(固定值TQ1828)
		infoVo.setFrontImage(imagUrl + "/" + identity.getIdFront());// String
		infoVo.setBackImage(imagUrl + "/" + identity.getIdBack());// String
		infoVo.setLiveBody(imagUrl + "/" + identity.getIdFace());// String
																	// 活体识别文件(base64)(解析后的活体照片)
		infoVo.setName(identity.getName());// String 客户姓名
		infoVo.setAge(Utility.getAgeFromBirthTime(identity.getBirthday().replace(".", "-")) + "");// String年龄
		infoVo.setSex(identity.getGender());// String 性别
		infoVo.setIdentityNo(identity.getCitizenId());// String 身份证号
		infoVo.setHouseholdAddr(identity.getAddress());// String 身份证户籍地址
		if (personalAddrList != null && personalAddrList.size() > 0) {
			for (AuthPersonalAddress authPersonalAddress : personalAddrList) {
				// 居住地
				if (liveStatus == authPersonalAddress.getAddressType()) {
					infoVo.setAddress(authPersonalAddress.getCityCode());// 现所在城市
					break;
				}
			}
		}
		infoVo.setHouseHold(HouseHoldEnum.getCodeByDesc(authPersonal.getCensusIsLiveCity()));// String

		infoVo.setMarriage(MarriageEnum.getCodeByDesc(authPersonal.getMarriageKey()));// String婚姻状况
		infoVo.setJobOnline(HlOccupationEnum.getCodeByDesc(authPersonal.getProfessionValue()));// String工作
		infoVo.setEducation(EducationEnum.getEducationName(authPersonal.getEducationValue()));// String
		// 学历
		infoVo.setPayHousingFund(authPersonal.getHasAccumulation() == 1 ? yes : no);// String
		infoVo.setFacePairResult(identity.getLiveCompareValue() + "");// String依图人脸识别对比评分结果
		infoVo.setMobileNo(mobile.getMobile());// String 手机号（手机认证）
		infoVo.setMobileReport(mobile.getMobileId());// String 手机报告ID
		infoVo.setMobileScore(netCredit.getMobileScore());// String手机评分(决策预审使用的手机评分)
		// 信用卡
		infoVo.setLendingCashCardBank(CreditCardBankEnum.getVbsByCode(creditcard.getBankType()));// String// 放款信用卡所属银行
		infoVo.setLendingCashCardNo(creditcard.getAccountNo());// String 放款信用卡卡号
		infoVo.setLendingMobile(custAccount.getUserName());// String 银行卡绑定手机号

		infoVo.setCreditReportId(netCredit.getReportId());// String 征信报告ID
		infoVo.setCreditReportNo(netCredit.getReportSn());// String 征信报告编号
		infoVo.setReportType(reportType);// String 征信报告类型默认10 外贸
		infoVo.setSignImage(imagUrl + "/" + netCredit.getSignatureImg());// String
																			// 图片签名(base64)
		infoVo.setProductType(productType);// String 产品类型(固定XYM)
		infoVo.setScorename(netCredit.getScoreName());// 评分名称(新增)
		infoVo.setModulename(netCredit.getScoreModuleName());// 模块名称(新增)

		return infoVo;
	}

	/**
	 * 加密
	 * 
	 * @param pwd
	 * @return
	 * @throws Exception
	 */
	public String password(String pwd) throws Exception {
		byte[] data = pwd.getBytes();
		byte[] encodedData = RSAUtil.encryptByPublicKey(data, publicKey);
		pwd = new String(Base64.encodeBase64(encodedData));
		return pwd;
	}
}
